import axios from 'axios';
import store from '@/store';
import md5 from '@/libs/md5';


// import CryptoJS from 'crypto-js'

axios.defaults.timeout = 10000;
const createRequest = Symbol('createRequest');
const mapTimer = Object.create(null);


// 请求拦截器
axios.interceptors.request.use((config) => {
    if (store.getters['user/userInfo'].token) { // 判断是否存在token，如果存在的话，则每个http header都加上token
        config.headers['Access-Token'] = store.getters['user/userInfo'].token;
    }
    return config;
}, error => Promise.reject(error));
// 响应拦截器即异常处理
axios.interceptors.response.use(response => response,
    err => Promise.resolve(err.response));

class Resource {
    constructor(url, baseURL) {
        this._url = url;
        this._baseURL = baseURL;

        this.mergeOptions = Object.create(null);
        this.requestUrl = '';
        this.param = '?';
        this.key = '';
        this.now = 0;
    }

    stream({ method = 'get', params = {}, option = {} } = {}) {
        const config = {
            method: method.toLowerCase(),
            baseURL: this._baseURL,
            url: this._url,
        };

        const options = {
            isFormData: true, // POST是否formData传参数
            isCache: false, // 是否缓存数据
            delayed: 60, // 缓存数据时长(秒)
            isDebounce: true, // 是否接口防抖
            debounceDelayed: 300, // 接口防抖时长(毫秒)
            headers: { // 配置请求头
                'content-type': method.toLowerCase() === 'post'
                    ? 'application/x-www-form-urlencoded'
                    : 'application/json',
            },
        };

        if (method.toLowerCase() === 'post') {
            const formData = new FormData();
            for (const key in params) {
                formData.append(key, params[key]);
            }
            options.isFormData ? config.data = formData : config.data = params;
        } else if (method.toLowerCase() === 'get') {
            config.params = params;
        }
        this.mergeOptions = Object.assign(options, option);
        this.requestUrl = this._baseURL + this._url;
        this.now = new Date().getTime() / 1000;
        for (const i in params) {
            if (i) this.param += `${i}=${params[i]}&`;
        }

        // 判断是否缓存
        if (this.mergeOptions.isCache) {
            const key = JSON.stringify(this.requestUrl + this.param.replace(/[&?]$/, ''));
            this.key = md5(key);
            const Cache = JSON.parse(localStorage.getItem(this.key));
            if (Cache) {
                // 判断是否超时以进行缓存
                const timeout = (Cache.time + options.delayed) < this.now;
                if (!timeout) {
                    return Cache.cacheData;
                }
            }
        }

        // 判断是否防抖
        return new Promise((resolve, reject) => {
            if (this.mergeOptions.isDebounce) {
                const key = JSON.stringify(this.requestUrl + this.param.replace(/[&?]$/, ''));
                const md5key = md5(key);
                if (mapTimer[md5key]) clearTimeout(mapTimer[md5key]);
                mapTimer[md5key] = setTimeout(() => {
                    const data = this[createRequest](config);
                    resolve(data);
                }, this.mergeOptions.debounceDelayed);
            } else {
                const data = this[createRequest](config);
                resolve(data);
            }
        });
    }

    // 私有方法
    async [createRequest](config) {
        const data = await axios.request(config);
        // 缓存数据
        if (this.mergeOptions.isCache) {
            localStorage.setItem(this.key, JSON.stringify({
                time: this.now,
                cacheData: data,
            }));
        }

        return data;
    }

    GET(params) {
        return axios.request({
            method: 'get',
            baseURL: this._baseURL,
            url: this._url,
            params,
        });
    }

    POST(params) {
        const formData = new FormData();
        for (const key in params) {
            formData.append(key, params[key]);
        }
        return axios.request({
            method: 'post',
            baseURL: this._baseURL,
            url: this._url,
            data: formData,
            headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8;' },
            onDownloadProgress(progressEvent) {
                console.log('progressEvent=>>>', progressEvent.loaded);
            },
        });
    }

    UPLOAD(params) {
        const formData = new FormData();
        for (const key in params) {
            formData.append(key, params[key]);
        }
        return axios.request({
            method: 'post',
            baseURL: this._baseURL,
            url: this._url,
            data: formData,
            headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8;' },
            onUploadProgress(progressEvent) {
                console.log('上传进度=>>>', progressEvent);
            },
        });
    }
}

// 副接口拼接
const stream = (URL, baseURL) => (url = '') => {
    const path = url ? (URL + url) : URL;
    return new Resource(path, baseURL);
};

export default stream;
